import pyautogui
import time
from queue import Queue
from typing import Dict,List
from PySide2.QtCore import QThread,QObject,Signal
from taskCilick.runClickThreadType import RunClickThreadType
from taskCilick.runClickThreadStatus import RunClickThreadStatus

class RunClickThread(QThread):

    SigMessage = Signal(str)
    SigTaskDone = Signal()
    SigAllLoopProgressValue = Signal(int)
    SigLoopProgressValue = Signal(int)
    SigRunTimeTotal = Signal(float)

    def __init__(self, task:Queue, parent: QObject = None) -> None:
        super().__init__(parent)

        self.task_queue = task
        self.begin_posi_list:List[Dict] = []
        self.loop_posi_list:List[Dict] = []
        self.ended_posi_list:List[Dict] = []
        self.all_loop_count = 1
        self.loop_count = 1
        self.cur_all_loop_count = 0
        self.cur_loop_count = 0
        self.begin_run_flag = True
        self.loop_run_flag = False
        self.ended_run_flag = False
        self.begin_posi_index = 0
        self.loop_posi_index = 0
        self.ended_posi_index = 0
        self.run_total_time = time.monotonic()
        self.run_status = RunClickThreadStatus.WAIT

    @staticmethod
    def percentage(part, total) -> int:

        return int(part / total * 100)

    def update_posi_info(self):

        main_central_widget = self.parent()
        data = main_central_widget.get_all_data_info()
        self.begin_posi_list = data[main_central_widget.FiledBeginPositionList]
        self.loop_posi_list = data[main_central_widget.FiledLoopPositionList]
        self.ended_posi_list = data[main_central_widget.FiledEndedPositionList]
        self.all_loop_count = data[main_central_widget.FiledAllLoopCount]
        self.loop_count = data[main_central_widget.FiledLoopCount]
        self.cur_all_loop_count = 0
        self.cur_loop_count = 0

    def run_posi_flag_index_reset(self):

        self.begin_run_flag = True
        self.loop_run_flag = False
        self.ended_run_flag = False
        self.begin_posi_index = 0
        self.loop_posi_index = 0
        self.ended_posi_index = 0
        self.cur_loop_count = 0
        self.SigLoopProgressValue.emit(0)

    def run_loop_start(self):

        self.update_posi_info()
        self.run_posi_flag_index_reset()
        self.run_status = RunClickThreadStatus.RUN
        self.run_total_time = time.monotonic()

    def run_click_position(self, posi_list:list, index:int) -> bool:
        """ 点击位置

        Args:
            posi_list (list): _description_
            index (int): _description_

            posi_list[index] 数据结构 = {
                "x": 1345,
                "y": 536,
                "interval": 1.0,
                "able": true,
                "marke": "2"
            }
        Returns:
            bool: _description_
        """
        try:
            data_info = posi_list[index]
            if data_info['able'] == False:
                return True
            self.SigMessage.emit("顺序:%d\tclick : %d, %d\t %s" % (index+1, data_info['x'], data_info['y'], data_info['marke']))
            # pyautogui.click(data_info['x'], data_info['y'],)
            time.sleep(data_info['interval'])
            return True
        except Exception:
            return False
    
    def run(self) -> None:

        while True:
            if self.isInterruptionRequested():
                self.SigMessage.emit('任务退出.')
                break
            
            if not self.task_queue.empty():
                task = self.task_queue.get()
                if task == RunClickThreadType.START:
                    self.SigMessage.emit('任务开始...')
                    self.run_loop_start()
                elif task == RunClickThreadType.PAUSE:
                    self.SigMessage.emit('任务已暂停.')
                    self.run_status = RunClickThreadStatus.PAUSE
                elif task == RunClickThreadType.CONTINUE:
                    self.run_status = RunClickThreadStatus.RUN
            
            if self.run_status != RunClickThreadStatus.RUN:
                time.sleep(0.1)
                continue
            
            if self.begin_run_flag:
                if self.begin_posi_index == 0:
                    self.SigMessage.emit('准备.')
                if self.run_click_position(self.begin_posi_list, self.begin_posi_index):
                    self.begin_posi_index += 1
                else:
                    self.SigMessage.emit('准备完成.')
                    self.begin_run_flag = False
                    self.loop_run_flag = True
            if self.loop_run_flag:
                if self.loop_posi_index == 0:
                    self.SigMessage.emit(f'主循环 {self.cur_loop_count+1}.')
                if self.run_click_position(self.loop_posi_list, self.loop_posi_index):
                    self.loop_posi_index += 1
                else:
                    self.loop_posi_index = 0
                    self.cur_loop_count += 1
                    self.SigLoopProgressValue.emit(self.percentage(self.cur_loop_count, self.loop_count))
                    if self.cur_loop_count >= self.loop_count:
                        self.SigMessage.emit(f'主循环完成.')
                        self.loop_run_flag = False
                        self.ended_run_flag = True
            if self.ended_run_flag:
                if self.ended_posi_index == 0:
                    self.SigMessage.emit('收尾.')
                if self.run_click_position(self.ended_posi_list, self.ended_posi_index):
                    self.ended_posi_index += 1
                else:
                    self.SigMessage.emit('收尾完成.')
                    self.ended_run_flag = False
                    self.cur_all_loop_count += 1
                    self.SigAllLoopProgressValue.emit(self.percentage(self.cur_all_loop_count, self.all_loop_count))
                    if self.cur_all_loop_count >= self.all_loop_count:
                        self.run_status = RunClickThreadStatus.WAIT
                        self.SigTaskDone.emit()
                        self.SigMessage.emit('任务结束,等待新的新的任务到来.')
                        self.SigRunTimeTotal.emit(time.monotonic()-self.run_total_time)
                    else:
                        self.run_posi_flag_index_reset()